package com.lc.pda.controller;

import com.alibaba.fastjson.JSONObject;
import com.lc.pda.util.WXBizMsgCrypt;
import lombok.extern.slf4j.Slf4j;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.client.RestTemplate;

import javax.annotation.Resource;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.BufferedReader;
import java.io.InputStream;
import java.io.InputStreamReader;

@Controller
@Slf4j
public class CallBackController {

    @Autowired
    private StringRedisTemplate redisTemplate;

    @Resource
    private RestTemplate restTemplate;

    // 指定回调接口
    @RequestMapping(path = "/callback")
    public void directCallback(HttpServletRequest request, HttpServletResponse response) {

        log.info("-----------进入回调接口-----------");
        response.setCharacterEncoding("UTF-8");

        try {
            String corpid = request.getParameter("corpid");
            String suiteId = request.getParameter("suiteId");
            corpid = corpid == null ? "wwcc5a4c8eb9a6c294" : corpid;
            // 企业微信加密签名
            String msgSignature = request.getParameter("msg_signature");
            // 时间戳 与nonce结合使用，用于防止请求重放攻击
            String timestamp = request.getParameter("timestamp");
            // 校验时字符串
            String echostr = request.getParameter("echostr");
            // 随机数 与timestamp结合使用，用于防止请求重放攻击
            String nonce = request.getParameter("nonce");

            System.out.println("msgSignature: " + msgSignature);
            System.out.println("timestamp: " + timestamp);
            System.out.println("echostr: " + echostr);
            System.out.println("nonce: " + nonce);
            if ("GET".equals(request.getMethod())) { // get请求表示是验证
                System.out.println("corpid:" + corpid);
                String echostrDecrypt;
                // 校验服务商公司id
                WXBizMsgCrypt wxcpt = new WXBizMsgCrypt("YMiy23G", "gVqyRznbTmCTpREQiPhyKj7c4HOKNB6Iupm79GBqQY9", corpid);
                echostrDecrypt = wxcpt.VerifyURL(msgSignature, timestamp, nonce, echostr);
                System.out.println("verifyurl echostr: " + echostrDecrypt);

                response.setCharacterEncoding("UTF-8");
                response.getWriter().write(echostrDecrypt);
            } else { // post请求表示是真实数据
                // 获取传过来的xml信息（密文）
                InputStream ins = request.getInputStream();
                BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(ins));
                StringBuilder postData = new StringBuilder();
                String line;
                while ((line = bufferedReader.readLine()) != null) {
                    postData.append(line);
                }
                System.out.println("postData:" + postData);

                WXBizMsgCrypt wxcpt = new WXBizMsgCrypt("YMiy23G", "gVqyRznbTmCTpREQiPhyKj7c4HOKNB6Iupm79GBqQY9", suiteId);
                String info = wxcpt.DecryptMsg(msgSignature, timestamp, nonce, postData.toString());
                System.out.println("解析的明文是：" + info); // 此处明文是xml信息

                // 解析xml，若InfoType是suite_ticket的话，说明是发送ticket的响应方式
                Document doc = DocumentHelper.parseText(info);
                Element root = doc.getRootElement();
                String infoType = root.elementTextTrim("InfoType");
                // 此处只是进行suite_ticket以及auth_code的处理，若是需要其他的处理需要在这里添加类型
                if ("suite_ticket".equals(infoType)) {
                    String suiteTicket = root.elementTextTrim("SuiteTicket");
                    System.out.println("拿到的ticket是: " + suiteTicket);
                    redisTemplate.opsForValue().set("wx-test:suiteTicket", suiteTicket);
                    // 获取到suiteTicket 调用微信接口获取suite_token
                    this.getSuiteAccessToken(suiteId, suiteTicket);
                } else if ("create_auth".equals(infoType)) {
                    String authCode = root.elementTextTrim("AuthCode");
                    System.out.println("拿到的authCode是：" + authCode);
                    redisTemplate.opsForValue().set("wx-test:authCode", authCode);
                    // 获取临时授权码 调用微信接口获取永久授权码
                    String suiteTicket = redisTemplate.opsForValue().get("wx-test:"+ corpid +":suiteTicket");
                    String suiteAccessToken = this.getSuiteAccessToken(suiteId, suiteTicket);
                    if (suiteAccessToken != null) {
                        JSONObject json = new JSONObject();
                        json.put("auth_code", authCode);
                        JSONObject resultJson = restTemplate.postForObject("https://qyapi.weixin.qq.com/cgi-bin/service/get_permanent_code?suite_access_token="
                                        + suiteAccessToken, json, JSONObject.class);
                        if (resultJson != null && Integer.parseInt(resultJson.getString("errcode")) == 0) {
                            String permanentCode = resultJson.getString("permanent_code");
                            redisTemplate.opsForValue().set("wx-test:permanentCode", permanentCode);

                        }
                    }
                }

                response.getWriter().write("success");
            }
            System.out.println("----------------------------");
        } catch (Exception e) {
            //验证URL失败，错误原因请查看异常
            e.printStackTrace();
        }
    }


    public String getSuiteAccessToken(String suiteId, String suiteTicket) {
        String suiteToken = redisTemplate.opsForValue().get("wx-test:suiteToken");
        if (suiteToken != null) {
            JSONObject json = new JSONObject();
            json.put("suite_id", suiteId);
            json.put("suite_secret", "H4uXT_Aq2ioqyD-N2aPTKLHprlybYEFL5pqtEXZyfjE");
            json.put("suite_ticket", suiteTicket);
            JSONObject resultJson = restTemplate.postForObject("https://qyapi.weixin.qq.com/cgi-bin/service/get_suite_token", json, JSONObject.class);
            if (resultJson != null && Integer.parseInt(resultJson.get("errcode").toString()) == 0) {
                suiteToken = resultJson.get("suite_access_token").toString();
                redisTemplate.opsForValue().set("wx-test:suiteToken", suiteToken, 5400);
            }
        }
        return suiteToken;
    }

    @RequestMapping("/redirect")
    public String redirect() {
        return "/index";
    }

}